package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.common.exception.ExceptionEnum;
import org.footballmanager.pandafootball.common.exception.MyException;
import org.footballmanager.pandafootball.common.util.DateUtils;
import org.footballmanager.pandafootball.system.dao.FootSjDao;
import org.footballmanager.pandafootball.system.domain.FootSj;
import org.footballmanager.pandafootball.system.domain.enums.BSJC;
import org.footballmanager.pandafootball.system.domain.enums.SJZT;
import org.footballmanager.pandafootball.system.form.impl.FootSjSearchForm;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@Service("footSjService")
public class FootSjServiceImpl extends ServiceImpl<FootSj> implements FootSjService {
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

    @Autowired
    private FootSjDao footSjDao;
    @Autowired
    private FootUserService footUserService;
    @Autowired
    private FootTeamService footTeamService;
    @Autowired
    private FootClubService footClubService;
    @Autowired
    private FootTtService footTtService;
    @Autowired
    private FootRankService footRankService;
    @Autowired
    private FootCupbmService footCupbmService;
    @Autowired
    private FootMissionService footMissionService;
    @Autowired
    private FootSociatyService footSociatyService;

    /**
     * 定时任务
     */
//    @Scheduled(fixedRate = 999999999) //调试用触发方式
    @Scheduled(cron = "0 0 0 * * ?") //每天0点触发
    @Transactional
    public void remind1() {
        footUserService.cancelLogin(true, null);
        //判断当日的赛季状态
        getSjStatus(new Date());
        footUserService.cancelLogin(false, null);
    }

    /**
     * 根据时间修改对应时间的数据
     *
     * @param date 时间
     */
    private void getSjStatus(Date date) {
        log.info("start Time:" + new Date().toString());
        try {
            processWeek(date);
            FootSj sj = findBySjbm(date);
            if (sj == null) {
                return;
            }
            int day = DateUtils.getNowDay(date);
            int endday = DateUtils.getMonthEnd(date);
            processDayInMonth(day, endday, sj, date);
            //是否破产
            //FootTeamServiceImpl.isPc()
            footMissionService.addNewMission(sj.getSjzt(), null);
        } catch (Exception e) {
            throw new MyException(ExceptionEnum.CODEEXCEPTION, e);
        }
        log.info("end Time:" + new Date().toString());
    }

    /**
     * 处理每天的数据
     *
     * @param day    当前日期的天数
     * @param endday 当前日期的本月最后一天
     * @param sj     赛季实体类
     * @param date   日期
     */
    private void processDayInMonth(int day, int endday, FootSj sj, Date date) {
        if (day == 1) {
            processFirstDay(sj);
        } else if (day == 21) {
            process21Day(sj);
        } else if (day == 23) {
            //结束八分之一决赛,开始四分之一决赛
            footCupbmService.endCupGames(2, null);
        } else if (day == 25) {
            //结束四分之一决赛,开始半决赛
            footCupbmService.endCupGames(3, null);
        } else if (day == 27) {
            //结束半决赛,开始决赛
            footCupbmService.endCupGames(4, null);
        } else if (day == 28) {
            process28Day(date, day, endday);
        } else if (day == endday) {
            processLastDay(date);
        }
    }

    /**
     * 处理第21天的赛季数据
     *
     * @param sj 赛季实体
     */
    @Override
    public void process21Day(FootSj sj) {
        //常规赛奖金发放
        footTeamService.fjl(sj.getId(), false, null);
        sj.setSjzt(SJZT.PLAYOFF);
        super.updateNotNull(sj, null);
        //获取常规赛的名次，并给杯赛分配队伍
        footCupbmService.addTeam2Table(null);
        //开始各种杯赛,开始八分之一决赛
        footCupbmService.endCupGames(1, null);
    }

    /**
     * 处理第28天的赛季数据
     *
     * @param date   时间
     * @param day    第day天
     * @param endday 本月的最后一天
     */
    @Override
    public void process28Day(Date date, int day, int endday) {
        if (day == endday) {
            footCupbmService.endCupGames(5, null);
            footTtService.reward(null);
            footRankService.reward(null);
            this.addNewSj(date, BSJC.NOTSTART);
        } else {
            footCupbmService.endCupGames(5, null);
        }
    }

    /**
     * 处理第一天的赛季数据
     *
     * @param sj 赛季实体
     */
    @Override
    public void processFirstDay(FootSj sj) {
        sj.setBsjc(BSJC.GOING);
        sj.setSjzt(SJZT.NORMAL);
        super.updateNotNull(sj, null);
        //应该把上赛季结束,本赛季开始
        FootSj lastSj = this.get(this.getLastSj());
        if (lastSj != null) {
            lastSj.setBsjc(BSJC.END);
            super.updateNotNull(lastSj, null);
        }
        //修改新的club记录
        footClubService.addNewClubInfo(this.getSj(), null);
    }

    /**
     * 处理最后一天的赛季数据
     *
     * @param date 时间
     */
    @Override
    public void processLastDay(Date date) {
        footTtService.reward(null);
        footRankService.reward(null);
        this.addNewSj(date, BSJC.NOTSTART);
    }

    /**
     * 查找赛季编码
     *
     * @param date 时间
     * @return 赛季实体
     */
    private FootSj findBySjbm(Date date) {
        String now = sdf.format(date);
        Example example = new Example(FootSj.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sjbm", now);
        criteria.andEqualTo("delFlag", 0);
        List<FootSj> list = this.findall(example);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 处理战队数据
     *
     * @param date 日期
     */
    private void processWeek(Date date) {
        int week = DateUtils.getWeekDay(date);
        if (week == 0 || week == 6) {
            footSociatyService.changeStatus(true, null);
        } else {
            footSociatyService.changeStatus(false, null);
        }
    }

    /**
     * 添加新赛季
     *
     * @param date 日期
     * @param bsjc 比赛进程
     * @return 新赛季实体类
     */
    private FootSj addNewSj(Date date, BSJC bsjc) {
        FootSj newsj = new FootSj();
        newsj.setBsjc(bsjc);
        Date lastDay = DateUtils.getNextMonthFirstDay(date);
        newsj.setSjbm(sdf.format(lastDay));
        newsj.setKsrq(lastDay);
        newsj.setJsrq(DateUtils.getNextMonthLastDay(date));
        newsj.setSjzt(SJZT.NORMAL);
        newsj.setCreateId(1L);
        newsj.setCreateTime(new Date());
        newsj.setUpdateId(1L);
        newsj.setUpdateTime(new Date());
        footSjDao.insert(newsj);
        return newsj;
    }

    /**
     * 获取当前赛季
     *
     * @return 赛季主键
     */
    @Override
    public Long getSj() {
        return this.getRunningSj().getId();
    }

    /**
     * 获取上个赛季的赛季主键
     *
     * @return 上赛季主键
     */
    @Override
    public Long getLastSj() {
        Example example = new Example(FootSj.class);
        example.createCriteria().andEqualTo("delFlag", 0);
        example.orderBy("id").desc();
        List<FootSj> list = this.findall(example);
        if (list != null && !list.isEmpty() && list.size() > 2) {
            return list.get(1).getId();
        }
        return null;
    }

    /**
     * 获取正在进行中的赛季信息
     *
     * @return 正在进行中的赛季信息
     */
    @Override
    public FootSj getRunningSj() {
        Example example = new Example(FootSj.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("bsjc", BSJC.GOING);
        criteria.andEqualTo("delFlag", 0);
        List<FootSj> list = this.findall(example);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        } else {
            return addNewSj(new Date(), BSJC.GOING);
        }
    }

    /**
     * 查询
     *
     * @param entityname       实体类名
     * @param map              参数
     * @param footSjSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootSjSearchForm footSjSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footSjSearchForm);
        Page<FootSj> page = PageHelper.startPage(footSjSearchForm.getPageIndex(), footSjSearchForm.getPageSize());
        List<FootSj> list = this.findall(footSjSearchForm.buildSearchCommond());
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 删除所有
     *
     * @param footSjSearchForm 条件
     * @param request          请求
     */
    @Override
    public void deleteAll(FootSjSearchForm footSjSearchForm, HttpServletRequest request) {
        if (footSjSearchForm.getSelectIds() != null) {
            String[] result = footSjSearchForm.getSelectIds().split(Constants.COMMA);
            for (String id : result) {
                this.delete(Long.parseLong(id), request);
            }
        }
    }
}
